import os
import cStringIO
import conf
from const import LOG_TYPE_INST, LOG_TYPE_TEST, LOG_TYPE_TESTGROUP, LOG_TYPE_NATR
from util import debug

LOG_CACHE = {}


LOG_TYPE_NAME = {
    LOG_TYPE_INST: 'inst',
    LOG_TYPE_TEST: 'test',
    LOG_TYPE_TESTGROUP: 'testg',
    LOG_TYPE_NATR: 'natr',
    'inst': LOG_TYPE_INST,
    'test': LOG_TYPE_TEST,
    'testg': LOG_TYPE_TESTGROUP,
    'natr': LOG_TYPE_NATR,
}
# log name field separator
LOGNFS = r'__'
def get_logid(hostname, tid=None):
    
    if tid:
        return LOGNFS.join((LOG_TYPE_NAME[LOG_TYPE_TEST], hostname, str(tid)))
    else:
        return LOGNFS.join((LOG_TYPE_NAME[LOG_TYPE_INST], hostname))

def get_testgid(hostname, bldno):
    return LOGNFS.join((LOG_TYPE_NAME[LOG_TYPE_TESTGROUP], hostname, bldno))

# get not available testrun id
def get_natrid(hostname, trid):
    return LOGNFS.join((LOG_TYPE_NAME[LOG_TYPE_NATR], hostname, str(trid)))

def get_logtype(id):
    return LOG_TYPE_NAME[id.split(LOGNFS)[0]]


def write_log(filename, content, flag='w'):
    with open(filename, flag) as log:
        log.write(content)


def read_log(filename):
    if not os.path.isfile(filename):
        return ""
    with open(filename, 'r') as log:
        return log.read()


def get_logpath(hostname, tid=None):
    if tid:
        return "%s/%s-%d.log" % (conf.TEST_LOGDIR, hostname, tid)
    else:
        return "%s/%s.log" % (conf.INST_LOGDIR, hostname)


#FIXME: read/write log functions here should be synchronized
def write_inst_log(hostname, content):
    logid = get_logid(hostname)
    if logid not in LOG_CACHE:
        # create a cache string for this machine if not exist
        LOG_CACHE[logid] = cStringIO.StringIO()
        # reload the existing log if exists
        exist_content = read_log(get_logpath(hostname))
        if exist_content:
            LOG_CACHE[logid].write(exist_content)

    # append the new log content to cache
    LOG_CACHE[logid].write(content)


def write_test_log(hostname, tid, content):
    logid = get_logid(hostname, tid)
    if logid not in LOG_CACHE:
        # create a cache string for this test if not exist
        LOG_CACHE[logid] = cStringIO.StringIO()
        # reload the existing log if exists
        exist_content = read_log(get_logpath(hostname, tid))
        if exist_content:
            LOG_CACHE[logid].write(exist_content)

    # append the new log content to cache
    LOG_CACHE[logid].write(content)


def read_inst_log(hostname):
    logid = get_logid(hostname)
    content = ""
    if logid in LOG_CACHE:
        content = LOG_CACHE[logid].getvalue()
    else:
        content = read_log(get_logpath(hostname))

    return content


def read_test_log(hostname, tid):
    logid = get_logid(hostname, tid)
    content = ""
    if logid in LOG_CACHE:
        content = LOG_CACHE[logid].getvalue()
    else:
        content = read_log(get_logpath(hostname, tid))

    return content


def flush_log(logid, logpath, content):
    if content:
        if logid in LOG_CACHE:
            LOG_CACHE[logid].write(content)
	else:
	    write_log(logpath, content, 'a')

    if logid in LOG_CACHE:
        write_log(logpath, LOG_CACHE[logid].getvalue())
        LOG_CACHE[logid].close()
        del LOG_CACHE[logid]

def flush_inst_log(hostname, content=""): 
    flush_log(get_logid(hostname),
	      get_logpath(hostname),
	      content)

def flush_test_log(hostname, tid, content=""): 
    flush_log(get_logid(hostname, tid),
	      get_logpath(hostname, tid),
	      content)


def clear_inst_log(hostname):
    log = get_logpath(hostname)
    if os.path.isfile(log):  
       os.remove(log)


